home *** CD-ROM | disk | FTP | other *** search
/ Scene 96 / Scene 96 International Edition (Zyklop Software) (Disc 2) (1997).iso / misc / coding / midas060 / src / rawfile.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-01-16  |  13.1 KB  |  516 lines

  1. /*      RAWFILE.C
  2.  *
  3.  * Raw file I/O for MIDAS Sound System
  4.  *
  5.  * $Id: rawfile.c,v 1.2 1997/01/16 18:41:59 pekangas Exp $
  6.  *
  7.  * Copyright 1996,1997 Housemarque Inc.
  8.  *
  9.  * This file is part of the MIDAS Sound System, and may only be
  10.  * used, modified and distributed under the terms of the MIDAS
  11.  * Sound System license, LICENSE.TXT. By continuing to use,
  12.  * modify or distribute this file you indicate that you have
  13.  * read the license and understand and accept it fully.
  14. */
  15.  
  16. #include <stdio.h>
  17. #include <stdlib.h>
  18. #include <errno.h>
  19. #include "lang.h"
  20. #include "mtypes.h"
  21. #include "errors.h"
  22. #include "mmem.h"
  23. #include "rawfile.h"
  24.  
  25. RCSID(const char *rawfile_rcsid = "$Id: rawfile.c,v 1.2 1997/01/16 18:41:59 pekangas Exp $";)
  26.  
  27.  
  28. /****************************************************************************\
  29. *
  30. * Function:     int ErrorCode(void)
  31. *
  32. * Description:  Get the MIDAS error code corresponding to errno.
  33. *
  34. * Returns:      MIDAS error code
  35. *
  36. \****************************************************************************/
  37.  
  38. static int ErrorCode(void)
  39. {
  40.     switch ( errno )
  41.     {
  42.         case ENOENT:
  43.             return errFileNotFound;
  44.  
  45.         case ENODEV:
  46.         #ifdef ENOPATH
  47.         case ENOPATH:
  48.         #endif
  49.             return errInvalidPath;
  50.  
  51.         case EMFILE:
  52.             return errTooManyFiles;
  53.  
  54.         case EBADF:
  55.             return errInvalidFileHandle;
  56.  
  57.         case EACCES:
  58.             return errAccessDenied;
  59.  
  60.         case ENOMEM:
  61.             return errOutOfMemory;
  62.  
  63.         case EEXIST:
  64.             return errFileExists;
  65.  
  66.         default:
  67.             return errUndefined;
  68.     }
  69. }
  70.  
  71.  
  72.  
  73.  
  74. /****************************************************************************\
  75. *
  76. * Function:     int rfOpen(char *fileName, int openMode, rfHandle *file);
  77. *
  78. * Description:  Opens a file for reading or writing
  79. *
  80. * Input:        char *fileName          name of file
  81. *               int openMode            file opening mode, see enum rfOpenMode
  82. *               rfHandle *file          pointer to file handle
  83. *
  84. * Returns:      MIDAS error code.
  85. *               File handle is stored in *file.
  86. *
  87. \****************************************************************************/
  88.  
  89. int CALLING rfOpen(char *fileName, int openMode, rfHandle *file)
  90. {
  91.     int         error;
  92.     rfHandle    hdl;
  93.  
  94.     /* allocate file structure */
  95.     if ( (error = memAlloc(sizeof(rfFile), (void**) &hdl)) != OK )
  96.         PASSERROR(ID_rfOpen)
  97.  
  98.     switch ( openMode )
  99.     {
  100.         case rfOpenRead:        /* open file for reading */
  101.             hdl->f = fopen(fileName, "rb");
  102.             break;
  103.  
  104.         case rfOpenWrite:       /* open file for writing */
  105.             hdl->f = fopen(fileName, "wb");
  106.             break;
  107.  
  108.         case rfOpenReadWrite:   /* open file for reading and writing */
  109.             hdl->f = fopen(fileName, "r+b");
  110.             break;
  111.     }
  112.  
  113.     /* If an error occurred during opening file, return the error code
  114.        specified by errno: */
  115.     if ( hdl->f == NULL )
  116.     {
  117.         error = ErrorCode();
  118.         ERROR(error, ID_rfOpen);
  119.         return error;
  120.     }
  121.  
  122.     /* store file handle in *file: */
  123.     *file = hdl;
  124.  
  125.     return OK;
  126. }
  127.  
  128.  
  129.  
  130.  
  131. /****************************************************************************\
  132. *
  133. * Function:     int rfClose(rfHandle file);
  134. *
  135. * Description:  Closes a file opened with rfOpen().
  136. *
  137. * Input:        rfHandle file           handle of an open file
  138. *
  139. * Returns:      MIDAS error code
  140. *
  141. \****************************************************************************/
  142.  
  143. int CALLING rfClose(rfHandle file)
  144. {
  145.     int         error;
  146.  
  147.     /* close file: */
  148.     if ( fclose(file->f) != 0 )
  149.     {
  150.         /* error occurred - return error code specified by errno: */
  151.         error = ErrorCode();
  152.         ERROR(error, ID_rfClose);
  153.         return error;
  154.     }
  155.  
  156.     /* deallocate file structure: */
  157.     if ( (error = memFree(file)) != OK )
  158.         PASSERROR(ID_rfClose)
  159.  
  160.     return OK;
  161. }
  162.  
  163.  
  164.  
  165.  
  166. /****************************************************************************\
  167. *
  168. * Function:     int rfGetSize(rfHandle file, long *fileSize);
  169. *
  170. * Description:  Get the size of a file
  171. *
  172. * Input:        rfHandle file           handle of an open file
  173. *               ulong *fileSize         pointer to file size
  174. *
  175. * Returns:      MIDAS error code.
  176. *               File size is stored in *fileSize.
  177. *
  178. \****************************************************************************/
  179.  
  180. int CALLING rfGetSize(rfHandle file, long *fileSize)
  181. {
  182.     int         error;
  183.     static long fpos;
  184.  
  185.     /* store current file position: */
  186.     if ( (error = rfGetPosition(file, &fpos)) != OK )
  187.         PASSERROR(ID_rfGetSize)
  188.  
  189.     /* seek to end of file: */
  190.     if ( (error = rfSeek(file, 0, rfSeekEnd)) != OK )
  191.         PASSERROR(ID_rfGetSize)
  192.  
  193.     /* read file position to *filesize: */
  194.     if ( (error = rfGetPosition(file, fileSize)) != OK )
  195.         PASSERROR(ID_rfGetSize)
  196.  
  197.     /* return original file position: */
  198.     if ( (error = rfSeek(file, fpos, rfSeekAbsolute)) != OK )
  199.         PASSERROR(ID_rfGetSize)
  200.  
  201.     return OK;
  202. }
  203.  
  204.  
  205.  
  206.  
  207. /****************************************************************************\
  208. *
  209. * Function:     int rfRead(rfHandle file, void *buffer, ulong numBytes);
  210. *
  211. * Description:  Reads binary data from a file
  212. *
  213. * Input:        rfHandle file           file handle
  214. *               void *buffer            reading buffer
  215. *               ulong numBytes          number of bytes to read
  216. *
  217. * Returns:      MIDAS error code.
  218. *               Read data is stored in *buffer, which must be large enough
  219. *               for it.
  220. *
  221. \****************************************************************************/
  222.  
  223. int CALLING rfRead(rfHandle file, void *buffer, ulong numBytes)
  224. {
  225.     FILE        *f = file->f;
  226.     int         error;
  227.     unsigned    readOK;
  228.  
  229. #ifdef __16__
  230.     ulong       readCount = numBytes;
  231.     uchar huge  *rbuf;
  232.  
  233.     /* 16-bit mode - data must be read at chunks of 49152 bytes */
  234.     rbuf = (uchar huge*) buffer;
  235.  
  236.     while ( readCount > 0 )
  237.     {
  238.         if ( readCount > 49152 )
  239.         {
  240.             /* More than 49152 bytes left to read - read 49152 bytes and
  241.                advance buffer pointer */
  242.             if ( (readOK = fread(rbuf, 49152, 1, f)) != 1 )
  243.                 break;
  244.             readCount -= 49152;
  245.             rbuf += 49152;
  246.         }
  247.         else
  248.         {
  249.             /* 49152 or less bytes remaining - read them to *rbuf */
  250.             if ( (readOK = fread(rbuf, readCount, 1, f)) != 1 )
  251.                 break;
  252.             readCount = 0;
  253.         }
  254.     }
  255.  
  256. #else
  257.     /* 32-bit mode - all data can be read with one call to fread */
  258.     readOK = fread(buffer, numBytes, 1, f);
  259. #endif
  260.  
  261.     if ( readOK != 1 )
  262.     {
  263.         /* Error occurred when reading file. Check if there is an error, and
  264.            if is, return an error code corresponding to errno: */
  265.         if ( ferror(f) )
  266.         {
  267.             error = ErrorCode();
  268.             ERROR(error, ID_rfRead);
  269.             return error;
  270.         }
  271.  
  272.         /* no error - check if end of file: */
  273.         if ( feof(f) )
  274.         {
  275.             ERROR(errEndOfFile, ID_rfRead);
  276.             return errEndOfFile;
  277.         }
  278.  
  279.         /* no error or end of file - return "Unable to read file" */
  280.         ERROR(errFileRead, ID_rfRead);
  281.         return errFileRead;
  282.     }
  283.  
  284.     return OK;
  285. }
  286.  
  287.  
  288.  
  289.  
  290. /****************************************************************************\
  291. *
  292. * Function:     int rfWrite(rfHandle file, void *buffer, ulong numBytes);
  293. *
  294. * Description:  Writes binary data to a file
  295. *
  296. * Input:        rfHandle file           file handle
  297. *               void *buffer            pointer to data to be written
  298. *               ulong numBytes          number of bytes to write
  299. *
  300. * Returns:      MIDAS error code
  301. *
  302. \****************************************************************************/
  303.  
  304. int CALLING rfWrite(rfHandle file, void *buffer, ulong numBytes)
  305. {
  306.     FILE        *f = file->f;
  307.     int         error;
  308.     unsigned    writeOK;
  309.  
  310. #ifdef __16__
  311.     ulong       writeCount = numBytes;
  312.     uchar huge  *wbuf;
  313.     /* 16-bit mode - data must be written in chunks of 49152 bytes */
  314.     wbuf = (uchar huge*) buffer;
  315.  
  316.     while ( writeCount > 0 )
  317.     {
  318.         if ( writeCount > 49152 )
  319.         {
  320.             /* More than 49152 bytes left to write - write 49152 bytes and
  321.                advance buffer pointer */
  322.             if ( (writeOK = fwrite(wbuf, 49152, 1, f)) != 1 )
  323.                 break;
  324.             writeCount -= 49152;
  325.             wbuf += 49152;
  326.         }
  327.         else
  328.         {
  329.             /* 49152 or less bytes remaining - write all */
  330.             if ( (writeOK = fwrite(wbuf, writeCount, 1, f)) != 1 )
  331.                 break;
  332.             writeCount = 0;
  333.         }
  334.     }
  335.  
  336. #else
  337.     /* 32-bit mode - all data can be written with one call to fwrite */
  338.     writeOK = fwrite(buffer, numBytes, 1, f);
  339. #endif
  340.     if ( writeOK != 1 )
  341.     {
  342.         /* Error occurred when writing file. Check if there is an error, and
  343.            if is, return an error code corresponding to errno: */
  344.         if ( ferror(f) )
  345.         {
  346.             error = ErrorCode();
  347.             ERROR(error, ID_rfWrite);
  348.             return error;
  349.         }
  350.  
  351.         /* no error - return "Unable to write file" */
  352.         ERROR(errFileWrite, ID_rfWrite);
  353.         return errFileWrite;
  354.     }
  355.  
  356.     return OK;
  357. }
  358.  
  359.  
  360.  
  361.  
  362.  
  363.  
  364.  
  365.  
  366. /****************************************************************************\
  367. *
  368. * Function:     int rfSeek(rfHandle file, long newPosition, int seekMode);
  369. *
  370. * Description:  Seeks to a new position in file. Subsequent reads and writes
  371. *               go to the new position.
  372. *
  373. * Input:        rfHandle file           file handle
  374. *               long newPosition        new file position
  375. *               int seekMode            file seek mode, see enum rfSeekMode
  376. *
  377. * Returns:      MIDAS error code
  378. *
  379. \****************************************************************************/
  380.  
  381. int CALLING rfSeek(rfHandle file, long newPosition, int seekMode)
  382. {
  383.     FILE        *f = file->f;
  384.     int         error;
  385.     int         fseekMode;
  386.  
  387.     /* select seek mode for fseek() corresponding to seekMode: */
  388.     switch ( seekMode )
  389.     {
  390.         case rfSeekAbsolute:            /* seek to an absolute offset */
  391.             fseekMode = SEEK_SET;
  392.             break;
  393.  
  394.         case rfSeekRelative:            /* seek relative to current */
  395.             fseekMode = SEEK_CUR;       /* position */
  396.             break;
  397.  
  398.         case rfSeekEnd:
  399.             fseekMode = SEEK_END;       /* seek from end of file */
  400.             break;
  401.  
  402.         default:
  403.             /* invalid seek mode: */
  404.             ERROR(errInvalidArguments, ID_rfSeek);
  405.             return errInvalidArguments;
  406.     }
  407.  
  408.     /* seek to new position: */
  409.     if ( fseek(f, newPosition, fseekMode) != 0 )
  410.     {
  411.         /* Error during seeking.  Check if there is an error, and if is,
  412.            return an error code corresponding to errno: */
  413.         if ( ferror(f) )
  414.         {
  415.             error = ErrorCode();
  416.             ERROR(error, ID_rfSeek);
  417.             return error;
  418.         }
  419.  
  420.         /* no error - return "Unable to read file" */
  421.         ERROR(errFileRead, ID_rfSeek);
  422.         return errFileRead;
  423.     }
  424.  
  425.     return OK;
  426. }
  427.  
  428.  
  429.  
  430.  
  431. /****************************************************************************\
  432. *
  433. * Function:     int rfGetPosition(rfHandle file, long *position);
  434. *
  435. * Description:  Reads the current position in a file
  436. *
  437. * Input:        rfHandle file           file handle
  438. *               long *position          pointer to file position
  439. *
  440. * Returns:      MIDAS error code.
  441. *               Current file position is stored in *position.
  442. *
  443. \****************************************************************************/
  444.  
  445. int CALLING rfGetPosition(rfHandle file, long *position)
  446. {
  447.     FILE        *f = file->f;
  448.     int         error;
  449.     long        fpos;
  450.  
  451.     /* get current position to fpos: */
  452.     if ( (fpos = ftell(f)) == -1L )
  453.     {
  454.         /* Error - if errno is nonzero, return error code corresponding
  455.            to it. Otherwise return undefined error. */
  456.         if ( errno )
  457.         {
  458.             error = ErrorCode();
  459.             ERROR(error, ID_rfGetPosition);
  460.             return error;
  461.         }
  462.         else
  463.         {
  464.             ERROR(errUndefined, ID_rfGetPosition);
  465.             return errUndefined;
  466.         }
  467.     }
  468.  
  469.     *position = fpos;                   /* store position in *position */
  470.  
  471.     return OK;
  472. }
  473.  
  474.  
  475.  
  476.  
  477. /****************************************************************************\
  478. *
  479. * Function:     int rfFileExists(char *fileName, int *exists);
  480. *
  481. * Description:  Checks if a file exists or not
  482. *
  483. * Input:        char *fileName          file name, ASCIIZ
  484. *               int *exists             pointer to file exists status
  485. *
  486. * Returns:      MIDAS error code.
  487. *               *exists contains 1 if file exists, 0 if not.
  488. *
  489. \****************************************************************************/
  490.  
  491. int CALLING rfFileExists(char *fileName, int *exists)
  492. {
  493.     FILE        *f;
  494.  
  495.     /* Attempt to open file using fopen(). If it succeeds, the file exists. */
  496.     if ( (f = fopen(fileName, "rb")) != NULL )
  497.     {
  498.         *exists = 1;
  499.         fclose(f);
  500.     }
  501.     else
  502.         *exists = 0;
  503.  
  504.     return OK;
  505. }
  506.  
  507.  
  508. /*
  509.  * $Log: rawfile.c,v $
  510.  * Revision 1.2  1997/01/16 18:41:59  pekangas
  511.  * Changed copyright messages to Housemarque
  512.  *
  513.  * Revision 1.1  1996/05/22 20:49:33  pekangas
  514.  * Initial revision
  515.  *
  516. */